#include <asm/timex.h>
#include <riscv/sbi.h>
#include <riscv/csr-ops.h>

#include <linux/sched.h>
#include <linux/clockchips.h>
#include <linux/jiffies.h>
#include <linux/irq.h>

#define CPUTIME_TIMER_FREQ 10000000

static volatile unsigned long tick_cycles = 0;


static struct clock_event_device riscv_clock_event = {
    
};

void timer_isr(void)
{
    cycles_t now;

    sbi_set_timer(~0UL);

    clockevents_handle(&riscv_clock_event);

    now = get_cycles();
    sbi_set_timer(now + tick_cycles);
}

#if 1
#ifndef CONFIG_IRQCHIP
static void _handle_irq(struct pt_regs *regs)
{
    if ((regs->cause & 0xff) == 5)
    {
        timer_isr();
    }
    else
    {
        printk("Unhandled IRQ: %d\n", regs->cause & 0xff);
    }
}
#endif

void timer_probe(void)
{
    clockevents_config_and_register(&riscv_clock_event, CPUTIME_TIMER_FREQ, 100, 100000);

    tick_cycles = CPUTIME_TIMER_FREQ / HZ;
    csr_clear(CSR_IE, SIP_STIP);

    sbi_set_timer(get_cycles() + tick_cycles);
    /* Enable the Supervisor-Timer bit in SIE */
    csr_set(CSR_IE, SIP_STIP);

#ifndef CONFIG_IRQCHIP
    set_handle_irq(_handle_irq);
#endif
}
#else
void timer_probe(void)
{
}
#endif
